# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: xguo

import sys
import json
import re
#import matplotlib
#matplotlib.use('Agg')
#import matplotlib.pyplot as plt
import datetime


def print_all(file):
  with open(file) as infile:
    content_list = json.load(infile)

  for content in content_list:
    if "data" in content and "private_exchange_message" in content["data"]:
      print(datetime.datetime.fromtimestamp(content["timestamp"] / 1e9),
            content['data']['request_id'])
      print(content["data"]["private_exchange_message"])
      print("==============")


def find_reqid(req_id, msg_list):
  for each in msg_list:
    if each[1] == req_id:
      return each


def print_allx(file):
  with open(file) as infile:
    content_list = json.load(infile)

  msg_list = []
  for content in content_list:
    if "data" in content and "private_exchange_message" in content["data"]:
      ts = datetime.datetime.fromtimestamp(content["timestamp"] / 1e9)
      req_id = content['data']['request_id']
      msg = content["data"]["private_exchange_message"]
      msg_list.append((ts, req_id, msg))
      if 'html' in msg:
        req_msg = find_reqid(req_id, msg_list)
        if req_msg is not None and 'matchresult' in req_msg[2]:
          print("ok")
        else:
          print("bad")
      # print(ts, req_id)
      # print(msg)
      # print("==============")


def print_simple(file):
  with open(file) as infile:
    content_list = json.load(infile)

  for content in content_list:
    if "data" in content and "private_exchange_message" in content["data"]:
      split_str = content["data"]["private_exchange_message"].split('\n')
      for str_arr in split_str:
        if str_arr.startswith('GET') or str_arr.startswith('{') or str_arr.startswith('['):
          print(str_arr)


def submit_response_elapse(file):
  with open(file) as infile:
    content_list = json.load(infile)

  elapse_dict = {}
  # "proc_order_id" : [
  #     event create time,
  #     event accept time,
  #     event cancel submit time,
  #     event cancel accept time,
  #     private message place order request time,
  #     private message place order response time,
  #     private message cancel order request time,
  #     private message cancel order response time,
  #     order_id
  #  ]
  for i in range(len(content_list)):
    content = content_list[i]
    if "event" in content["data"] and "type" in content["data"]["event"]:
      proc_id = content["data"]["event"]["proc_order_id"]
      if content["data"]["event"]["type"] == "ORDER_SUBMITTED":
        elapse_dict[proc_id] = [0] * 9
        elapse_dict[proc_id][0] = int(content["data"]["event"]["order_created_time"])
      elif content["data"]["event"]["type"] == "ORDER_ACCEPTED":
        if proc_id in elapse_dict:
          elapse_dict[proc_id][1] = content["timestamp"]
          elapse_dict[proc_id][8] = content["data"]["event"]["external_order_id"]
      elif content["data"]["event"]["type"] == "CANCEL_SUBMITTED":
        if proc_id in elapse_dict:
          elapse_dict[proc_id][2] = content["timestamp"]
      elif content["data"]["event"]["type"] == "CANCEL_ACCEPTED":
        if proc_id in elapse_dict:
          elapse_dict[proc_id][3] = content["timestamp"]
    elif "private_exchange_message" in content["data"]:
      is_place_order = content["data"]["private_exchange_message"].startswith(
          "POST /api/spot/v3/orders")
      is_cancel_order = content["data"]["private_exchange_message"].startswith(
          "POST /api/spot/v3/cancel")
      if is_place_order or is_cancel_order:
        if is_place_order:
          ts_pos = 4
        else:
          ts_pos = 6
        split_str = re.split('[\r\n,]', content["data"]["private_exchange_message"])
        for str_arr in split_str:
          proc_id = ""
          if str_arr.startswith('{\"client_oid\"') and is_place_order:
            proc_id = str_arr[17:-1]
          elif str_arr.startswith('\"order_id\"') and is_cancel_order:
            order_id = str_arr[12:-2]
            for key in elapse_dict:
              if elapse_dict[key][8] == order_id:
                proc_id = key
                break
          if proc_id in elapse_dict:
            elapse_dict[proc_id][ts_pos] = content["timestamp"]
            # find response
            for j in range(i + 1, min(i + 100, len(content_list))):
              if "request_id" in content_list[j]["data"] and \
                  content_list[j]["data"]["request_id"] == content["data"]["request_id"]:
                elapse_dict[proc_id][ts_pos + 1] = content_list[j]["timestamp"]
                break
            break

  print("=" * 20)
  for key in elapse_dict:
    if elapse_dict[key][7] > 0:
      print(key, elapse_dict[key])
      print((elapse_dict[key][1] - elapse_dict[key][0]) / 1e9,
            (elapse_dict[key][3] - elapse_dict[key][2]) / 1e9,
            (elapse_dict[key][5] - elapse_dict[key][4]) / 1e9,
            (elapse_dict[key][7] - elapse_dict[key][6]) / 1e9)


def request_frequency(file):
  with open(file) as infile:
    content_list = json.load(infile)

  request_dict = {
      "query_accounts": "GET /api/spot/v3/accounts",
      "query_orders": "GET /api/spot/v3/orders?",
      "query_fills": "GET /api/spot/v3/fills?",
      "place_order": "POST /api/spot/v3/orders",
      "cancel_order": "POST /api/spot/v3/cancel_orders"
  }
  request_last_ts_dict = {
      "query_accounts": 0, "query_orders": 0, "query_fills": 0, "place_order": 0, "cancel_order": 0
  }
  request_interval_dict = {
      "query_accounts": [],
      "query_orders": [],
      "query_fills": [],
      "place_order": [],
      "cancel_order": []
  }
  for key in request_dict:
    for content in content_list:
      if "private_exchange_message" in content["data"] and \
          content["data"]["private_exchange_message"].startswith(request_dict[key]):
        if request_last_ts_dict[key] != 0:
          request_interval_dict[key].append(
              (content["timestamp"] - request_last_ts_dict[key]) / 1e9)
        request_last_ts_dict[key] = content["timestamp"]
    print(request_interval_dict[key])
    print(len(request_interval_dict[key]))
    print('-' * 50)
    plt.bar(range(len(request_interval_dict[key])), request_interval_dict[key], 0.1)
    # plt.show()
    plt.savefig('test1_' + key + '.png')
    plt.clf()
    plt.cla()

  last_query_ts = 0
  queries_arr = []
  for content in content_list:
    for key in request_dict:
      if "private_exchange_message" in content["data"] and \
          content["data"]["private_exchange_message"].startswith(request_dict[key]):
        if content["timestamp"] - last_query_ts > 1e9:
          queries_arr.append(1)
          last_query_ts = content["timestamp"]
        else:
          queries_arr[-1] += 1
        break
  print(queries_arr)
  print(len(queries_arr))
  plt.bar(range(len(queries_arr)), queries_arr)
  plt.savefig('test1_queries_arr.png')


def main(argv):
  file_name = argv[1]
  print_all(file_name)


if __name__ == '__main__':
  # print_simple(file_name)
  # submit_response_elapse(file_name)
  # request_frequency(file_name)
  main(sys.argv)
